home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / xsokoban / score.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  6.9 KB  |  271 lines

  1. #include <stdio.h>
  2. #include <signal.h>
  3. #include <sys/types.h>
  4. #include <netinet/in.h>
  5. #include "sokoban.h"
  6.  
  7. extern FILE *fopen();
  8.  
  9. extern char  *username;
  10. extern short scorelevel, scoremoves, scorepushes;
  11.  
  12. static short scoreentries;
  13. static struct {
  14.    char user[MAXUSERNAME];
  15.    unsigned short lv, pad1, mv, pad2, ps, pad3;
  16. } scoretable[MAXSCOREENTRIES];
  17.  
  18. static FILE *scorefile;
  19. static long sfdbn;
  20.  
  21. short outputscore() {
  22.  
  23.    short ret;
  24.  
  25.    while( creat( LOCKFILE, 0666) < 0);    /* lock the score file */
  26.    if( (ret = readscore()) == 0)
  27.       showscore();
  28.    unlink( LOCKFILE);
  29.    return( (ret == 0) ? E_ENDGAME : ret);
  30. }
  31.  
  32. short makenewscore() {
  33.  
  34.    short ret = 0;
  35.  
  36.    while( creat( LOCKFILE, 0666) < 0) ;
  37.    scoreentries = 0;
  38. #ifdef __MSDOS__
  39.    if( (scorefile = fopen( SCOREFILE, "wb")) == NULL)
  40.       ret = E_FOPENSCORE;
  41.    else {
  42.     if (fwrite (&scoreentries, 1, sizeof( scoreentries), scorefile) != sizeof(scoreentries))
  43.         ret = E_WRITESCORE;
  44. #else
  45.    if( (scorefile = fopen( SCOREFILE, "w")) == NULL)
  46.       ret = E_FOPENSCORE;
  47.    else {
  48.       sfdbn = fileno( scorefile);
  49.       if( write( sfdbn, &scoreentries, 2) != 2) ret = E_WRITESCORE;
  50. #endif
  51.       fclose( scorefile);
  52.    }
  53.    unlink( LOCKFILE);
  54.    return( (ret == 0) ? E_ENDGAME : ret);
  55. }
  56.  
  57. short getuserlevel( lv)
  58. short *lv;
  59. {
  60.    short ret = 0, pos;
  61.  
  62.    while( creat( LOCKFILE, 0666) < 0);
  63. #ifdef __MSDOS__
  64.    if( (scorefile = fopen( SCOREFILE, "rb")) == NULL)
  65. #else
  66.    if( (scorefile = fopen( SCOREFILE, "r")) == NULL)
  67. #endif
  68.       ret = E_FOPENSCORE;
  69.    else {
  70.       if( (ret = readscore()) == 0)
  71.      *lv = ( (pos = finduser()) > -1) ? scoretable[pos].lv+1 : 1;
  72.    }
  73.    unlink( LOCKFILE);
  74.    return( ret);
  75. }
  76.  
  77. short score() {
  78.    
  79.    short ret;
  80.  
  81.    while( creat( LOCKFILE, 0666) < 0);    /* lock the score file */
  82.    if( (ret = readscore()) == 0)
  83.       if( (ret = makescore()) == 0)
  84.      if( (ret = writescore()) == 0)
  85.         showscore();
  86.    unlink( LOCKFILE);
  87.    return( (ret == 0) ? E_ENDGAME : ret);
  88. }
  89.  
  90. readscore() {
  91.  
  92.    short ret = 0;
  93.    long tmp;
  94.  
  95. #ifdef __MSDOS__
  96.    if( (scorefile = fopen( SCOREFILE, "rb")) == NULL)
  97.       ret = E_FOPENSCORE;
  98.    else {
  99.       tmp = sizeof( scoreentries);
  100.       if( fread( &scoreentries, 1, tmp, scorefile) != tmp) ret = E_READSCORE;
  101.       else {
  102.      tmp = scoreentries * sizeof( scoretable[0]);
  103.      if( fread( scoretable, 1, tmp, scorefile) != tmp) ret = E_READSCORE;
  104.       }
  105. #else
  106.    if( (scorefile = fopen( SCOREFILE, "r")) == NULL)
  107.       ret = E_FOPENSCORE;
  108.    else {
  109.       sfdbn = fileno( scorefile);
  110.       if( read( sfdbn, &scoreentries, 2) != 2) ret = E_READSCORE;
  111.       else {
  112.      scoreentries = ntohs(scoreentries);
  113.      tmp = scoreentries * sizeof( scoretable[0]);
  114.      if( read( sfdbn, &(scoretable[0]), tmp) != tmp) ret = E_READSCORE;
  115.  
  116.     /* swap up for little-endian machines */
  117.      for(tmp = 0; tmp < scoreentries; tmp++) {
  118.         scoretable[tmp].lv = ntohs(scoretable[tmp].lv);
  119.         scoretable[tmp].mv = ntohs(scoretable[tmp].mv);
  120.         scoretable[tmp].ps = ntohs(scoretable[tmp].ps);
  121.      }
  122.       }
  123. #endif
  124.       fclose( scorefile);
  125.    }
  126.    return( ret);
  127. }
  128.  
  129. makescore() {
  130.  
  131.    short ret = 0, pos, i, build = 1, insert;
  132.  
  133.    if( (pos = finduser()) > -1) {    /* user already in score file */
  134.       insert =    (scorelevel > scoretable[pos].lv)
  135.            || ( (scorelevel == scoretable[pos].lv) &&
  136.                     (scoremoves < scoretable[pos].mv)
  137.           )
  138.            || ( (scorelevel == scoretable[pos].lv) &&
  139.             (scoremoves == scoretable[pos].mv) &&
  140.             (scorepushes < scoretable[pos].ps)
  141.           );
  142.       if( insert) {             /* delete existing entry */
  143.      for( i = pos; i < scoreentries-1; i++)
  144.         cp_entry( i, i+1);
  145.      scoreentries--;
  146.       }
  147.       else build = 0;
  148.    }
  149.    else if( scoreentries == MAXSCOREENTRIES)
  150.       ret = E_TOMUCHSE;
  151.    if( (ret == 0) && build) {
  152.       pos = findpos();            /* find the new score position */
  153.       if( pos > -1) {            /* score table not empty */
  154.      for( i = scoreentries; i > pos; i--)
  155.         cp_entry( i, i-1);
  156.       }
  157.       else pos = scoreentries;
  158.  
  159.       strcpy( scoretable[pos].user, username);
  160.       scoretable[pos].lv = scorelevel;
  161.       scoretable[pos].mv = scoremoves;
  162.       scoretable[pos].ps = scorepushes;
  163.       scoreentries++;
  164.    }
  165.    return( ret);
  166. }
  167.  
  168. finduser() {
  169.  
  170.    short i, found = 0;
  171.  
  172.    for( i = 0; (i < scoreentries) && (! found); i++)
  173.       found = (strcmp( scoretable[i].user, username) == 0);
  174.    return( (found) ? i-1 : -1);
  175. }
  176.  
  177. findpos() {
  178.  
  179.    short i, found = 0;
  180.  
  181.    for( i = 0; (i < scoreentries) && (! found); i++)
  182.       found =    (scorelevel > scoretable[i].lv)
  183.           || ( (scorelevel == scoretable[i].lv) &&
  184.                    (scoremoves < scoretable[i].mv)
  185.          )
  186.           || ( (scorelevel == scoretable[i].lv) &&
  187.            (scoremoves == scoretable[i].mv) &&
  188.            (scorepushes < scoretable[i].ps)
  189.          );
  190.    return( (found) ? i-1 : -1);
  191. }
  192.  
  193. writescore() {
  194.  
  195.    short ret = 0;
  196.    long tmp;
  197.  
  198. #ifdef __MSDOS__
  199.    if( (scorefile = fopen( SCOREFILE, "wb")) == NULL)
  200.       ret = E_FOPENSCORE;
  201.    else {
  202.       tmp = sizeof( scoreentries);
  203.       if( fwrite( &scoreentries, 1, tmp, scorefile) != tmp) ret = E_WRITESCORE;
  204.       else {
  205.      tmp = scoreentries * sizeof( scoretable[0]);
  206.      if( fwrite( scoretable, 1, tmp, scorefile) != tmp) ret = E_WRITESCORE;
  207.       }
  208. #else
  209.    if( (scorefile = fopen( SCOREFILE, "w")) == NULL)
  210.       ret = E_FOPENSCORE;
  211.    else {
  212.       sfdbn = fileno( scorefile);
  213.       scoreentries = htons(scoreentries);
  214.       if( write( sfdbn, &scoreentries, 2) != 2) ret = E_WRITESCORE;
  215.       else {
  216.          scoreentries = ntohs(scoreentries);
  217.  
  218.     /* swap around for little-endian machines */
  219.      for(tmp = 0; tmp < scoreentries; tmp++) {
  220.         scoretable[tmp].lv = htons(scoretable[tmp].lv);
  221.         scoretable[tmp].mv = htons(scoretable[tmp].mv);
  222.         scoretable[tmp].ps = htons(scoretable[tmp].ps);
  223.      }        
  224.      tmp = scoreentries * sizeof( scoretable[0]);
  225.      if( write( sfdbn, &(scoretable[0]), tmp) != tmp) ret = E_WRITESCORE;
  226.  
  227.      /* and swap back for the rest of the run ... */
  228.      for(tmp = 0; tmp < scoreentries; tmp++) {
  229.         scoretable[tmp].lv = ntohs(scoretable[tmp].lv);
  230.         scoretable[tmp].mv = ntohs(scoretable[tmp].mv);
  231.         scoretable[tmp].ps = ntohs(scoretable[tmp].ps);
  232.      }        
  233.  
  234.       }
  235. #endif
  236.       fclose( scorefile);
  237.    }
  238.    return( ret);
  239. }
  240.  
  241. showscore() {
  242.  
  243.    register short lastlv = 0, lastmv = 0, lastps = 0, i;
  244.  
  245.    fprintf( stdout, "Rank        User     Level     Moves    Pushes\n");
  246.    fprintf( stdout, "==============================================\n");
  247.    for( i = 0; i < scoreentries; i++) {
  248.       if( (scoretable[i].lv == lastlv)&& 
  249.       (scoretable[i].mv == lastmv) && 
  250.       (scoretable[i].ps == lastps))
  251.      fprintf( stdout, "      ");
  252.       else {
  253.          lastlv = scoretable[i].lv;
  254.          lastmv = scoretable[i].mv;
  255.          lastps = scoretable[i].ps;
  256.          fprintf( stdout, "%4d  ", i+1);
  257.       }
  258.       fprintf( stdout, "%10s  %8d  %8d  %8d\n", scoretable[i].user, 
  259.         scoretable[i].lv, scoretable[i].mv, scoretable[i].ps);
  260.    }
  261. }
  262.  
  263. cp_entry( i1, i2)
  264. register short i1, i2;
  265. {
  266.    strcpy( scoretable[i1].user, scoretable[i2].user);
  267.    scoretable[i1].lv = scoretable[i2].lv;
  268.    scoretable[i1].mv = scoretable[i2].mv;
  269.    scoretable[i1].ps = scoretable[i2].ps;
  270. }
  271.